' max3d entity viewer

Strict

Import axe3d.m3d
Import pub.glew

Import "../maxtk/maxtk.bmx"

Import "fileb3d.bmx"
Import "maxgui3d.bmx"

Type TEntityPlugin Extends TPlugin
	Field	editor:TEditor
'	Field	options:TTextOptions
'	Field	editmenu:TGadget

	Method Open:Object(path$)
		Return TEntityView.Open(Self,path)
	End Method
	
	Method Initialize(owner:THost)
		host=owner
		SetName("Entity",["3ds","b3d"])
		editor=TEditor(host)
		If Not editor RuntimeError "EntityPlugin requires TEditor Host"
'		options=New TTextOptions.CreateTextOptions(Self)
'		editmenu=CreateEditMenu()
		SetGraphicsDriver GLGraphicsDriver(),GRAPHICS_BACKBUFFER'|GRAPHICS_DEPTHBUFFER|GRAPHICS_STENCILBUFFER
	End Method

End Type

Type TEntityNode Extends TDataNode
	Field	owner:TEntityView
	Field	b3dnode:TB3DNode
	
	Method Invoke(command$,argument:Object=Null)
		Select command
			Case "ACTIVATE"
'				owner.ShowPos(pos)
		End Select
	End Method

	Method Sync(snap:TDataNode)
		Local	n:TEntityNode		
		If snap.name<>name SetName(snap.name)
		n=TEntityNode(snap)
		If n b3dnode=n.b3dnode'pos=n.pos;count=n.count
		Super.Sync(snap)
	End Method
	
	Method SetName(n$)
		Local	p
		p=n.find("'")
		If p<>-1 n=n[..p]
		name=n.Trim()
	End Method
		
	Method AttachKids()
		If b3dnode.kids
			For Local n:TB3DNode=EachIn b3dnode.kids
				Local k:TEntityNode=New TEntityNode.CreateEntityNode(owner,n)
				Append k
				k.AttachKids
			Next
		EndIf
	End Method
	
	Method CreateEntityNode:TEntityNode(_owner:TEntityView,_node:TB3DNode)
		Local	n$
		owner=_owner
		b3dnode=_node
		n=b3dnode.name		
		If b3dnode.mesh n:+" "+b3dnode.mesh.ToString()
		SetName n
		Return Self		
	End Method
	
End Type



Type TEntityView Extends TToolPanel
	Field	host:THost
	Field	canvas:TGadget
	Field	timer:TTimer

	Field	camera
	Field	light
	Field	cube

	Field yellow
	Field green
	Field ground
	
	Field	b3dentity:TB3DEntity

	Field	model
	Field	entity

	Field	yaw#,pitch#,dist#=-10
	Field	yawspeed#,pitchspeed#,zoomfactor#=1.0
	
'	Field	max3d:TGLMax3DDriver2
	
	Method Create:TEntityView(plugin:TEntityPlugin,src:TB3DEntity,file$)
		Local	stream:TStream		
'		model=_model
'		entity=_entity
		b3dentity=src
		timer=CreateTimer(25)		
		host=plugin.host
		path=host.FullPath(file)		
		name=StripDir(path)
		host.AddPanel Self
		canvas=CreateCanvas(0,0,ClientWidth(panel),ClientHeight(panel),panel,0)
		canvas.SetLayout 1,1,1,1
		ActivateGadget canvas		
'		host.AddRecent path
	
'		max3d=TGLMax3dDriver2.Open()
'		SetMax3DDriver max3d
'		m3dSetAmbientColor .2,.2,.2
		
'		light=m3dCreatePointLight()
'		m3dMoveEntity light,0,10,0
'		m3dSetLightRange light,100
'		cube=loadmesh(CreateBoxModel( .5,.5,.5,WhiteBrush() ))
		
'		model=src.BuildModel()
'		entity=LoadMesh(model)
		
		Return Self
	End Method


	Method InitWorld(maxwidth,maxheight)
		InitMax3D m3dimporter	
		SetClearColor 0,.1,.4
		camera=CreateCamera()
		MoveEntity camera,0,2,-2
		light=CreatePointLight()
		MoveEntity light,6,10,-10
		yellow=CreateMaterial()
		SetMaterialColor yellow,"DiffuseColor",1,1,0
		entity=CreateBox( yellow,1,1,1,2,0 )
		MoveEntity entity,0,2,0
		SetAmbientColor .5,.5,.5
		green=CreateMaterial()
		SetMaterialColor green,"DiffuseColor",0,1,0
		ground=CreateBox( green,100,.1,100,2,0 )
	End Method

	Method DrawWorld()
		Local w,h
		SetGraphics CanvasGraphics(canvas)
		w=GraphicsWidth()
		h=GraphicsHeight()
		Global init
		If Not init
			w=ClientWidth(Desktop())
			h=ClientHeight(Desktop())
			InitWorld(w,h)
			init=True
		EndIf
'		If lost Return
		SetCameraViewport camera,0,0,w,h
		TurnEntity entity,0,1,0
		RenderWorld
'		Cls
		Flip 
	End Method

	
	Method Render()	
		DrawWorld 
	End Method
	
	Field	entitynode:TDataNode

	Method GetNode:TDataNode()		
		Local	root:TDataNode
		Local	brushes:TDataNode
		Local	textures:TDataNode
		
		root=New TDataNode.Create(StripDir(path))
		
		If b3dentity
			If b3dentity.brushlist.Count()
				brushes=root.AddNode("Brushes")
				For Local brush:TB3DBrush=EachIn b3dentity.brushlist
					brushes.AddNode brush.name
				Next
			EndIf
			If b3dentity.texturelist.Count()
				textures=root.AddNode("Textures")
				For Local texture:TB3DTexture=EachIn b3dentity.texturelist
					textures.AddNode texture.name
				Next			
			EndIf
			
			Local b3droot:TEntityNode
			
			b3droot=New TEntityNode.CreateEntityNode(Self,b3dentity.root)
			b3droot.AttachKids		
			root.Append b3droot
		EndIf
		
		If EntityNode
			EntityNode.Sync(root)	
			root.Free
		Else
			EntityNode=root
		EndIf
		Return EntityNode
	End Method
	
	Method Update()
		yaw:+yawspeed
		pitch:+pitchspeed
		dist:*zoomfactor
		If entity
			TurnEntity entity,yaw,pitch,0
		EndIf
	End Method
	
	Method OnEvent()
		Select EventID()
		Case EVENT_TIMERTICK
			Update
			RedrawGadget canvas
		Case EVENT_GADGETPAINT
			Render
		Case EVENT_KEYDOWN
			Select EventData()
			Case KEY_DOWN
				pitchspeed=4
			Case KEY_UP
				pitchspeed=-4
			Case KEY_LEFT
				yawspeed=-4
			Case KEY_RIGHT
				yawspeed=4
			Case KEY_Z
				zoomfactor=1.125
			Case KEY_A
				zoomfactor=1/1.125
			Case KEY_ESCAPE
				End
			End Select
		Case EVENT_KEYUP
			Select EventData()
			Case KEY_DOWN,KEY_UP
				pitchspeed=0
			Case KEY_LEFT,KEY_RIGHT
				yawspeed=0
			Case KEY_A,KEY_Z
				zoomfactor=1
			End Select
		End Select
	End Method

	Method Invoke(command$,argument:Object=Null)
		Local	file$,ex$
		Local	p,res
		Select command
			Case "SHOW"
				If canvas ActivateGadget canvas
				host.SetTitle path				
				host.SetCodeNode GetNode()
			Case "CLOSE"
				host.RemovePanel Self
			Case "ACTIVATE"
				If canvas ActivateGadget canvas
			Case "SAVE"
			Case "QUICKSAVE" 
			Case "SAVEAS"
			Case "GOTO"
			Case "FIND"
			Case "FINDNEXT"
			Case "REPLACE"
			Case "BUILD"
			Case "RUN"
			Case "LOCK"
			Case "UNLOCK"
			Case "HELP"
			Case "UNDO"
			Case "REDO"
			Case "REFRESH"
			Case "CUT"
			Case "COPY"
			Case "PASTE"
			Case "SELECTALL" 
		End Select
	End Method

	Function Open:TEntityView(plugin:TEntityPlugin,path$)
'		Local	model:TModel	
		Local	b3dentity:TB3DEntity
		Local	view:TEntityView	
		Local	modeldir$,olddir$
		
		olddir=CurrentDir$()		
		modeldir=ExtractDir(RealPath(path))
		ChangeDir modeldir	

		b3dentity=LoadB3D(path)

'		model=LoadModel3DS( path )		
'		If Not model 
'			model=LoadModelB3D( path )
'			entity=LoadEntity( path )
'		EndIf
		ChangeDir olddir
		Print CurrentDir$()
'		If Not model Return Null
		view=New TEntityView.Create(plugin,b3dentity,path)		
		Return view
	End Function

End Type



Rem
		Local w,h
				
		Global _init
					
		SetGraphics CanvasGraphics(canvas)
		w=GraphicsWidth()
		h=GraphicsHeight()

		If Not _init
			glewInit
			glFrontFace GL_CW		
			Max3dGraphics ClientWidth(Desktop()),ClientHeight(Desktop())
'			m3dInit "SHADOWS=TRUE"
			SetClearColor 0,.1,.4				
			camera=CreateCamera()
			MoveEntity camera,0,2,-2
			_init=_init+1
		EndIf
		
		If camera
			w=GraphicsWidth()
			h=GraphicsHeight()
			SetCameraViewport camera,0,0,w,h		
			UpdateWorld
			RenderWorld
			Flip
		EndIf
		
'		SetGraphics CanvasGraphics(canvas)
'		glViewport 0,0,GraphicsWidth(),GraphicsHeight()
'		max3d.vpWidth=GraphicsWidth()
'		max3d.vpheight=GraphicsHeight()
'		UpdateWorld
'		RenderWorld	
EndRem
